JavaScript-dagi asinxron generator funksiyalariga chuqur kirish, asinxron iteratsiya protokollari, foydalanish holatlari va zamonaviy veb-ishlab chiqish uchun amaliy misollarni o'rganish.
Asinxron Generator Funksiyalari: Asinxron Iteratsiya Protokollarini O'zlashtirish
Asinxron dasturlash zamonaviy JavaScript ishlab chiqishning asosiy tamal toshidir, ayniqsa API-lardan ma'lumotlarni olish, fayllarni o'qish yoki ma'lumotlar bazalari bilan ishlash kabi I/O (kiritish/chiqarish) operatsiyalari bilan ishlaganda. An'anaviy ravishda, biz ushbu asinxron vazifalarni boshqarish uchun Promislar (Promises) va async/await-ga tayanganmiz. Biroq, asinxron generator funksiyalari asinxron iteratsiyani boshqarishning kuchli va oqlangan usulini taklif qiladi, bu bizga ma'lumotlar oqimini asinxron va samarali qayta ishlash imkonini beradi.
Asinxron Iteratsiya Protokollarini Tushunish
Asinxron generator funksiyalariga sho'ng'ishdan oldin, ularning asosida yotgan asinxron iteratsiya protokollarini tushunish muhim. Bu protokollar asinxron ma'lumotlar manbalari qanday qilib boshqariladigan va oldindan aytib bo'ladigan tarzda iteratsiya qilinishini belgilaydi.
Asinxron Iterable Protokoli
Asinxron iterable protokoli asinxron tarzda iteratsiya qilinishi mumkin bo'lgan obyektni belgilaydi. Agar obyekt asinxron iteratorni qaytaradigan Symbol.asyncIterator
kaliti bilan belgilangan metodga ega bo'lsa, u ushbu protokolga mos keladi.
Iterable-ni qo'shiqlar pleylisti kabi tasavvur qiling. Asinxron iterable esa har bir qo'shiq ijro etilishidan oldin yuklanishi (asinxron) kerak bo'lgan pleylistga o'xshaydi.
Misol:
const asyncIterable = {
[Symbol.asyncIterator]() {
return {
next() {
// Keyingi qiymatni asinxron ravishda olish
}
};
}
};
Asinxron Iterator Protokoli
Asinxron iterator protokoli asinxron iterator amalga oshirishi kerak bo'lgan metodlarni belgilaydi. Ushbu protokolga mos keladigan obyekt next()
metodiga va ixtiyoriy ravishda return()
va throw()
metodlariga ega bo'lishi kerak.
- next(): Bu metod ikki xususiyatga ega bo'lgan obyekt bilan yakunlanadigan Promiseni qaytaradi:
value
vadone
.value
ketma-ketlikdagi keyingi qiymatni o'z ichiga oladi vadone
iteratsiya tugaganligini ko'rsatuvchi mantiqiy qiymatdir. - return(): (Ixtiyoriy) Bu metod
value
vadone
xususiyatlariga ega bo'lgan obyekt bilan yakunlanadigan Promiseni qaytaradi. Bu iterator yopilayotganini bildiradi. Bu resurslarni bo'shatish uchun foydalidir. - throw(): (Ixtiyoriy) Bu metod xatolik bilan rad etiladigan Promiseni qaytaradi. U iteratsiya paytida xatolik yuz berganini bildirish uchun ishlatiladi.
Misol:
const asyncIterator = {
next() {
return new Promise((resolve) => {
// Keyingi qiymatni asinxron ravishda olish
setTimeout(() => {
resolve({ value: /* qandaydir qiymat */, done: false });
}, 100);
});
},
return() {
return Promise.resolve({ value: undefined, done: true });
},
throw(error) {
return Promise.reject(error);
}
};
Asinxron Generator Funksiyalari Bilan Tanishtiruv
Asinxron generator funksiyalari asinxron iteratorlar va iterable-larni yaratishning qulayroq va o'qilishi oson usulini taqdim etadi. Ular generatorlarning kuchi bilan Promiselarning asinxronligini birlashtiradi.
Sintaksis
Asinxron generator funksiyasi async function*
sintaksisidan foydalanib e'lon qilinadi:
async function* myAsyncGenerator() {
// Bu yerda asinxron operatsiyalar va yield operatorlari
}
yield
Kalit So'zi
Asinxron generator funksiyasi ichida yield
kalit so'zi qiymatlarni asinxron ravishda ishlab chiqarish uchun ishlatiladi. Har bir yield
operatori generator funksiyasining bajarilishini unga berilgan Promise hal bo'lguncha samarali ravishda to'xtatib turadi.
Misol:
async function* fetchUsers() {
const user1 = await fetch('https://example.com/api/users/1').then(res => res.json());
yield user1;
const user2 = await fetch('https://example.com/api/users/2').then(res => res.json());
yield user2;
const user3 = await fetch('https://example.com/api/users/3').then(res => res.json());
yield user3;
}
Asinxron Generatorlarni for await...of
Yordamida Ishlatish
Siz for await...of
sikli yordamida asinxron generator funksiyasi tomonidan ishlab chiqarilgan qiymatlar bo'yicha iteratsiya qilishingiz mumkin. Bu sikl generator tomonidan berilgan Promiselarning asinxron hal qilinishini avtomatik tarzda boshqaradi.
Misol:
async function main() {
for await (const user of fetchUsers()) {
console.log(user);
}
}
main();
Asinxron Generator Funksiyalari Uchun Amaliy Foydalanish Holatlari
Asinxron generator funksiyalari asinxron ma'lumotlar oqimlarini o'z ichiga olgan stsenariylarda, masalan:
1. API-lardan Ma'lumotlarni Oqim Bilan Uzatish
Paginatsiyani qo'llab-quvvatlaydigan API-dan katta hajmdagi ma'lumotlar to'plamini olishni tasavvur qiling. Butun ma'lumotlar to'plamini bir vaqtning o'zida olish o'rniga, siz ma'lumotlar sahifalarini bosqichma-bosqich olish va uzatish uchun asinxron generator funksiyasidan foydalanishingiz mumkin.
Misol (Paginatsiyalangan Ma'lumotlarni Olish):
async function* fetchPaginatedData(url, pageSize = 10) {
let page = 1;
while (true) {
const response = await fetch(`${url}?page=${page}&pageSize=${pageSize}`);
const data = await response.json();
if (data.length === 0) {
return; // Boshqa ma'lumot yo'q
}
for (const item of data) {
yield item;
}
page++;
}
}
async function main() {
for await (const item of fetchPaginatedData('https://api.example.com/data')) {
console.log(item);
}
}
main();
Xalqaro Misol (Valyuta Kursi API):
async function* fetchExchangeRates(currencyPair, startDate, endDate) {
let currentDate = new Date(startDate);
while (currentDate <= new Date(endDate)) {
const dateString = currentDate.toISOString().split('T')[0]; // YYYY-MM-DD
const url = `https://api.exchangerate.host/${dateString}?base=${currencyPair.substring(0,3)}&symbols=${currencyPair.substring(3,6)}`;
try {
const response = await fetch(url);
const data = await response.json();
if (data.success) {
yield {
date: dateString,
rate: data.rates[currencyPair.substring(3,6)],
};
}
} catch (error) {
console.error(`${dateString} uchun ma'lumotlarni olishda xatolik:`, error);
// Siz xatolarni boshqacha hal qilishingiz mumkin, masalan, qayta urinish yoki sanani o'tkazib yuborish.
}
currentDate.setDate(currentDate.getDate() + 1);
}
}
async function main() {
const currencyPair = 'EURUSD';
const startDate = '2023-01-01';
const endDate = '2023-01-10';
for await (const rate of fetchExchangeRates(currencyPair, startDate, endDate)) {
console.log(rate);
}
}
main();
Ushbu misol ma'lum bir sana oralig'i uchun kunlik EUR dan USD ga valyuta kurslarini oladi. U API chaqiruvlari paytida yuzaga kelishi mumkin bo'lgan xatolarni boshqaradi. `https://api.exchangerate.host` manzilini ishonchli va mos API nuqtasi bilan almashtirishni unutmang.
2. Katta Hajmdagi Fayllarni Qayta Ishlash
Katta hajmdagi fayllar bilan ishlaganda, butun faylni xotiraga o'qish samarasiz bo'lishi mumkin. Asinxron generator funksiyalari faylni qatorma-qator yoki qismlarga bo'lib o'qishga, har bir qismni asinxron ravishda qayta ishlashga imkon beradi.
Misol (Katta Faylni Qatorma-qator O'qish - Node.js):
const fs = require('fs');
const readline = require('readline');
async function* readLines(filePath) {
const fileStream = fs.createReadStream(filePath);
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity
});
for await (const line of rl) {
yield line;
}
}
async function main() {
for await (const line of readLines('large_file.txt')) {
// Har bir qatorni asinxron ravishda qayta ishlash
console.log(line);
}
}
main();
Ushbu Node.js misoli fs.createReadStream
va readline.createInterface
yordamida faylni qatorma-qator o'qishni namoyish etadi. readLines
asinxron generator funksiyasi har bir qatorni asinxron ravishda uzatadi.
3. Real-Time Ma'lumotlar Oqimlarini Boshqarish (WebSockets, Server-Sent Events)
Asinxron generator funksiyalari WebSockets yoki Server-Sent Events (SSE) kabi manbalardan keladigan real-time ma'lumotlar oqimlarini qayta ishlash uchun juda mos keladi. Siz oqimdan ma'lumotlar kelishi bilan ularni doimiy ravishda uzatishingiz mumkin.
Misol (WebSocket-dan Ma'lumotlarni Qayta Ishlash - Konseptual):
// Bu konseptual misol bo'lib, 'ws' (Node.js) kabi WebSocket kutubxonasini yoki brauzerning o'rnatilgan WebSocket API-sini talab qiladi.
async function* processWebSocketStream(url) {
const websocket = new WebSocket(url);
websocket.onmessage = (event) => {
//Buni generator tashqarisida boshqarish kerak.
//Odatda, siz event.data-ni navbatga qo'shasiz
//va generator navbatdan asinxron ravishda ma'lumotlar mavjud bo'lganda hal bo'ladigan
//Promise orqali ma'lumotlarni tortib oladi.
};
websocket.onerror = (error) => {
//Xatolarni boshqaring.
};
websocket.onclose = () => {
//Yopilishni boshqaring.
}
//Haqiqiy yield va navbatni boshqarish shu yerda sodir bo'ladi,
//websocket.onmessage hodisasi va asinxron generator funksiyasi
//o'rtasida sinxronizatsiya qilish uchun Promiselardan foydalaniladi.
//Bu soddalashtirilgan tasvirdir.
//while(true){ //Agar hodisalarni to'g'ri navbatga qo'ygan bo'lsangiz, buni ishlating.
// const data = await new Promise((resolve) => {
// // Navbatda ma'lumotlar mavjud bo'lganda promisen-i hal qiling.
// })
// yield data
//}
}
async function main() {
// for await (const message of processWebSocketStream('wss://example.com/ws')) {
// console.log(message);
// }
console.log("WebSocket misoli - faqat konseptual. Tafsilotlar uchun koddagi izohlarga qarang.");
}
main();
WebSocket misoli haqida muhim eslatmalar:
- Taqdim etilgan WebSocket misoli asosan konseptualdir, chunki WebSocket-ning hodisalarga asoslangan tabiatini asinxron generatorlar bilan to'g'ridan-to'g'ri integratsiya qilish Promiselar va navbatlardan foydalangan holda ehtiyotkorlik bilan sinxronizatsiyani talab qiladi.
- Haqiqiy dunyo ilovalari odatda kiruvchi WebSocket xabarlarini navbatda buferlashni va yangi ma'lumotlar mavjud bo'lganda asinxron generatorga signal berish uchun Promise-dan foydalanishni o'z ichiga oladi. Bu generatorning ma'lumotlarni kutish paytida bloklanmasligini ta'minlaydi.
4. Maxsus Asinxron Iteratorlarni Amalga Oshirish
Asinxron generator funksiyalari har qanday asinxron ma'lumotlar manbai uchun maxsus asinxron iteratorlarni yaratishni osonlashtiradi. Siz qiymatlarni olish, qayta ishlash va uzatish uchun o'zingizning mantiqingizni belgilashingiz mumkin.
Misol (Sonlar Ketma-ketligini Asinxron Yaratish):
async function* generateNumbers(start, end, delay) {
for (let i = start; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, delay));
yield i;
}
}
async function main() {
for await (const number of generateNumbers(1, 5, 500)) {
console.log(number);
}
}
main();
Ushbu misol start
dan end
gacha bo'lgan sonlar ketma-ketligini har bir son o'rtasida belgilangan delay
(kechikish) bilan yaratadi. await new Promise(resolve => setTimeout(resolve, delay))
qatori asinxron kechikishni kiritadi.
Xatolarni Boshqarish
Asinxron generator funksiyalari bilan ishlashda xatolarni boshqarish juda muhim. Asinxron operatsiyalar paytida yuzaga keladigan xatolarni boshqarish uchun generator funksiyasi ichida try...catch
bloklaridan foydalanishingiz mumkin.
Misol (Asinxron Generatorda Xatolarni Boshqarish):
async function* fetchData(url) {
try {
const response = await fetch(url);
const data = await response.json();
yield data;
} catch (error) {
console.error('Ma\'lumotlarni olishda xatolik:', error);
// Siz xatoni qayta yuborishni, standart qiymatni uzatishni yoki iteratsiyani to'xtatishni tanlashingiz mumkin.
// Masalan, yield { error: error.message };
throw error;
}
}
async function main() {
try {
for await (const data of fetchData('https://example.com/api/invalid')) {
console.log(data);
}
} catch (error) {
console.error('Iteratsiya davomida xatolik:', error);
}
}
main();
Ushbu misol fetch
operatsiyasi paytida yuzaga kelishi mumkin bo'lgan xatolarni qanday boshqarishni ko'rsatadi. try...catch
bloki har qanday xatolarni ushlaydi va ularni konsolga chiqaradi. Siz shuningdek, generator iste'molchisi tomonidan ushlanishi uchun xatoni qayta yuborishingiz yoki xato obyektini uzatishingiz mumkin.
Asinxron Generator Funksiyalaridan Foydalanishning Afzalliklari
- Kodning O'qilishi Osonlashadi: Asinxron generator funksiyalari an'anaviy Promise-ga asoslangan yondashuvlarga qaraganda asinxron iteratsiya kodini o'qilishi oson va qo'llab-quvvatlanadigan qiladi.
- Soddalashtirilgan Asinxron Boshqaruv Oqimi: Ular asinxron mantiqni ifodalashning tabiiyroq va ketma-ket usulini ta'minlaydi, bu esa uni tushunishni osonlashtiradi.
- Resurslarni Samarali Boshqarish: Ular ma'lumotlarni qismlarga yoki oqimlarga bo'lib qayta ishlashga imkon beradi, bu esa xotira sarfini kamaytiradi va ishlash samaradorligini oshiradi, ayniqsa katta ma'lumotlar to'plamlari yoki real-time ma'lumotlar oqimlari bilan ishlaganda.
- Mas'uliyatlarning Aniq Ajratilishi: Ular ma'lumotlarni yaratish mantig'ini ma'lumotlarni iste'mol qilish mantig'idan ajratadi, bu esa modullik va qayta foydalanishni rag'batlantiradi.
Boshqa Asinxron Yondashuvlar Bilan Taqqoslash
Asinxron Generatorlar vs. Promislar (Promises)
Promislar asinxron operatsiyalar uchun asos bo'lsa-da, ular asinxron qiymatlar ketma-ketligini boshqarish uchun unchalik mos emas. Asinxron generatorlar asinxron ma'lumotlar oqimlarini iteratsiya qilishning yanada tizimli va samarali usulini ta'minlaydi.
Asinxron Generatorlar vs. RxJS Observables
RxJS Observables asinxron ma'lumotlar oqimlarini boshqarish uchun yana bir kuchli vositadir. Observables ma'lumotlar oqimlarini o'zgartirish, filtrlash va birlashtirish uchun operatorlar kabi ilg'or xususiyatlarni taklif etadi. Biroq, asinxron generatorlar oddiy asinxron iteratsiya stsenariylari uchun ko'pincha ishlatish osonroqdir.
Brauzer va Node.js Muvofiqligi
Asinxron generator funksiyalari zamonaviy brauzerlarda va Node.js da keng qo'llab-quvvatlanadi. Ular ES2018 (ECMAScript 2018) ni qo'llab-quvvatlaydigan barcha asosiy brauzerlarda va Node.js ning 10 va undan yuqori versiyalarida mavjud.
Agar siz eski muhitlarni qo'llab-quvvatlashingiz kerak bo'lsa, kodingizni JavaScriptning eski versiyalariga transpilyatsiya qilish uchun Babel kabi vositalardan foydalanishingiz mumkin.
Xulosa
Asinxron generator funksiyalari JavaScript asinxron dasturlash vositalari to'plamiga qimmatli qo'shimchadir. Ular asinxron iteratsiyani boshqarishning kuchli va oqlangan usulini taqdim etadi, bu esa ma'lumotlar oqimlarini samarali va qo'llab-quvvatlanadigan tarzda qayta ishlashni osonlashtiradi. Asinxron iteratsiya protokollarini va asinxron generator funksiyalarining sintaksisini tushunib, siz ularning afzalliklaridan API-lardan ma'lumotlarni oqim bilan uzatishdan tortib, katta fayllarni qayta ishlash va real-time ma'lumotlar oqimlarini boshqarishgacha bo'lgan keng ko'lamli ilovalarda foydalanishingiz mumkin.
Qo'shimcha O'rganish Uchun
- MDN Web Docs: AsyncGeneratorFunction
- Exploring ES2018: Asynchronous Iteration
- Node.js Hujjatlari: Oqimlar va fayl tizimi operatsiyalari uchun rasmiy Node.js hujjatlariga murojaat qiling.